#ifndef CORTEXM_ITM_H
#define CORTEXM_ITM_H

typedef unsigned char  U8;
typedef unsigned short U16;
typedef unsigned int   U32;

typedef struct
{
    volatile union
    {
        volatile U8  u8;  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
        volatile U16 u16; /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
        volatile U32 u32; /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
    } PORT[32];           /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
    U32          RESERVED0[864];
    volatile U32 TER; /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
    U32          RESERVED1[15];
    volatile U32 TPR; /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
    U32          RESERVED2[15];
    volatile U32 TCR; /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
    U32          RESERVED3[29];
    volatile U32 IWR;  /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
    volatile U32 IRR;  /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
    volatile U32 IMCR; /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
    U32          RESERVED4[43];
    volatile U32 LAR; /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
    volatile U32 LSR; /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
    U32          RESERVED5[6];
    volatile U32 PID4; /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
    volatile U32 PID5; /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
    volatile U32 PID6; /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
    volatile U32 PID7; /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
    volatile U32 PID0; /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
    volatile U32 PID1; /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
    volatile U32 PID2; /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
    volatile U32 PID3; /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
    volatile U32 CID0; /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
    volatile U32 CID1; /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
    volatile U32 CID2; /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
    volatile U32 CID3; /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
} ITM_Type;

#define ITM ((ITM_Type*)0xE0000000UL)

#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
#define ITM_TCR_ITMENA_Msk                 (1UL << ITM_TCR_ITMENA_Pos) 


static __inline U32 ITM_SendChar(U32 ch)
{
    if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
        (ITM->TER & (1UL << 0)))           /* ITM Port #0 enabled */
    {
        while (ITM->PORT[0].u32 == 0)
            ;
        ITM->PORT[0].u8 = (U8)ch;
    }
    return (ch);
}

#endif
